Repository navigation
viewer: selection callout, interaction sounds and drone mode - #1227
Conversation
A selected element in the viewer gets the marketing house's callout: a dot,
a hairline, its name and kind ("Single-hung window"), one pill per action
(open or close, lights, shutters, moving parts, sliders) and a close button.
It replaces the floating On/Open buttons that popped on every item of a
selected room, on both the parametric and the baked paths. A click in orbit
now only selects; doors open from the pill.
Operating something plays its sound (door, window, garage, shutters, switch)
through a new `interaction:sound` event the editor's SFX bus plays; the
walkthrough's E and click play the same sounds. Door and shutter recordings
come from the /next house, the switch from scripts/synth-switch-cues.ts.
The viewer gains drone mode beside the walkthrough: one flight
implementation (`drone-flight.ts`, `DroneController`) that the snapshot
capture drone now runs on too, a Drone button in the viewer bar, and a hint
strip in the walkthrough HUD.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The callout keeps the house's dusk palette on every scene (the light-theme dark ink went grey over night scenes), its actions stay on one row with the close button after the last pill, and the pills take the house's sizes. A selected room gets the callout too: its name and area at a point inside it, and the close button. Hovering, selecting and deselecting tick as on the house (its "Minimal" kit cues, MIT); the switches use its pitch sweeps. scripts/synth-viewer-cues.ts renders all five, replacing synth-switch-cues.ts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Closing a door or a window now swings shut, then latches on the frame the leaf lands: built-in leaves and sashes wait for their animation-completed event (`openingSettled`), baked ones for the rest of their reversed clip. The swing is a new soft air cue (door_swing.mp3, synthesized in scripts/synth-viewer-cues.ts); windows play both quieter. Shutters clap as they land; garage doors keep their motor from the press. The walkthrough's E and click time their sounds the same way. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A procedural item's hinged part (a cabinet door, a lid) swings shut and claps as it lands; a sliding part (a drawer) claps as it lands; both open with the panel recording, as the marketing house plays its cabinets. The motion controller reports when its opening and sliding parts are at rest (`settled`, ignoring spinning ones), both runtimes announce it as `procedural:motion-settled` for the commanded run, and `proceduralSettled` lets the callout and the walkthroughs wait for it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit ee16c5e. Configure here.
|
|
||
| const target = interactableTargetRef.current ?? resolveInteractableTarget() | ||
| if (!target) return | ||
| playTargetSound(target) |
There was a problem hiding this comment.
Close latch can fire too early
Medium Severity
Walkthrough plays the closing sound by waiting for the next settle event before the toggle runs. A second E while a door, window, or recipe part is still opening therefore hears the in-flight open finish as a latch, and the real close never gets one. Pending waits are also not tied to the command that started them, so reversing an action can clap on the wrong landing.
Additional Locations (2)
Reviewed by Cursor Bugbot for commit ee16c5e. Configure here.
| else openIds.current.delete(id) | ||
| setOpenVersion((version) => version + 1) | ||
| // Played backwards from where it stands, the clip lands after its current time. | ||
| if (!willOpen) return new Promise<void>((resolve) => setTimeout(resolve, action.time * 1000)) |
There was a problem hiding this comment.
Baked close timer is never cancelled
Medium Severity
Closing a baked door or window returns a setTimeout for the remaining clip time and never clears it. Opening or closing again before that timer fires still lets the old callback run, so the latch can sound while the leaf is opening or twice on a later close.
Reviewed by Cursor Bugbot for commit ee16c5e. Configure here.


What does this PR do?
A viewer pass: selection, actions and camera modes.
interaction:soundevent, which the editor's SFX bus plays.door:/window:animation-completed. Baked clips use the remaining clip time. Recipes use a newprocedural:motion-settledevent, backed by the motion controller'ssettledflag.useViewerUiSounds).scripts/synth-viewer-cues.ts.drone-flight.ts,DroneControllerin viewer), and the snapshot capture drone now runs on it too.How to test
Automated, run locally:
bun testin packages/viewer (1333 pass), packages/editorsrc/components src/lib(2594 pass), packages/coresrc/procedural-items, packages/nodessrc/procedural-item.tsgo --noEmitfor core, viewer, editor and nodes.bun run check(warnings only, all pre-existing),bun run i18n:check,bun scripts/i18n-literals.ts check.New strings have fr/es/ja/zh-CN drafts flagged for review.
Screenshots / screen recording
Not added yet.
Checklist
bun devbun checkto verify)mainbranchTested in the hosted community viewer on parametric and baked scenes (headless Chrome), not through the standalone app's
bun dev.🤖 Generated with Claude Code
Note
Medium Risk
Substantial viewer/editor interaction, audio, and camera-path changes—selection vs activation and sound timing could regress, but scope stays within immersive modes rather than auth or persistence.
Overview
Selection and baked GLB. Orbit clicks now only change selection; doors, windows, shutters, mechanisms, recipe parts, and catalog items expose actions through a new SelectionCallout (and GlbSelectionCallout on baked scenes) with localized titles and pills, plus room callouts for name and area. The old floating ControlWidget overlays on GLB scenes are removed.
Sounds. Core adds
interaction:soundandprocedural:motion-settled; the editor SFX bus maps them to new door/window/garage/shutter/panel/switch and UI cue clips. ProceduralMotionController exposessettled(open/slide rest; spins ignored) and procedural render/GLB playback emit motion-settled when a command completes.openingSettled/proceduralSettledcoordinate swing-then-latch audio; walkthrough E/click and first-person playTargetSound share the mapping.useViewerUiSoundsadds hover/select/deselect ticks outside walkthrough until the page is user-activated.Drone. Shared
drone-flightpowers DroneController in the viewer, the editor snapshot/first-person drone path, and DroneHud key hints; useViewer trackswalkthroughMovement(walk|drone) so orbit vs walk vs drone modes stay distinct. Viewer controls bar gains a Drone button (desktop); exports and tests cover flight math and callout builders.i18n / baseline. New viewer/editor strings for callouts, drone hints, and controls; literal baseline drops obsolete control-widget entries.
Reviewed by Cursor Bugbot for commit ee16c5e. Bugbot is set up for automated code reviews on this repo. Configure here.